//2014-4-2  programed by sixbeauty
//zeromp Õ®—∂≤‚ ‘server ∂À
#include "zmq.h"
#include "zmq_utils.h"            
#include "json.h"
#include<ctime>
//#include <windows.h> 
//#pragma comment(lib,"libzmq-v100-mt-gd-4_0_4.lib")
//#include <stdio.h>
//#include <string.h>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include "HCNetSDK.h"
#include "curl.h"
#include "LOG.h"
//#include "SSDB_impl.cpp"
#include <signal.h> 
#include <sys/param.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#define LOG_STYLES_HELLO        ( LOG_STYLE_DATETIMEMS | LOG_STYLE_LOGLEVEL |  LOG_STYLE_SOURCE | LOG_STYLE_FORMAT | LOG_STYLE_NEWLINE )
//#define POSTURL "http://192.168.2.152:13202/vss/2.0/test/post_data"
#define POSTURL "http://192.168.2.133:80/secline/gcs/application/upload_hkdj_new2"
using namespace std;  
const char*   tb_clpp[15]={"未知品牌","大众","别克","宝马","本田","标致","福特","日产","奥迪","马自达","雪弗兰","雪铁龙","现代","奇瑞"};
const char*  tb_csys[13]={"未知颜色","白色","银色","灰色","黑色","红色","深蓝","蓝色","黄色","绿色","棕色","粉色","紫色"};
const char*  tb_wfxwdm[14]={"00000","43060","","13010","16251","13451","12081","12110","10760","13451","12081","13445","12110","12110"};
const char*   tb_hpys[5] = {"2","1","0","3","4"};
#define DEBUG 0
#define INFO  1
#define WORN 2
#define ERROR 3
#define FATAL 4
typedef struct {
     unsigned int length; /* 数据长度 */
    unsigned char *data;  /* 数据 */
} GraphData;
typedef struct resive{
	char resend_url[100];
	int url_status;
}Resive;
Resive *resend;
typedef struct  HK_PHOTO_INFO{
char	cd[10];		//车道
unsigned char    *jgsj;	//时间
char    zpxh[10];				//连拍的图片序号
char    *hphm;		//车牌号码
char    hpys[20];//车牌颜色
char    clsd[3];		//速度
char    wfdm[10];  //wfxwdm
char   *zb;//fx;
char    csys[20];//车身颜色	
char    clpp[8];  //车标
char   txxh[10];	//车辆序号
char   *sbip;    			/* IP地址 */
char    cllk[1];	//车辆轮廓			
GraphData	 qjtx; //gfilel
GraphData	 pBuffer2; //gfile2 
GraphData	 pBuffer3; //驾驶员图片
GraphData	 pBuffer4; //副驾驶图片			
}PHOTO_INFO;

typedef struct _globleInfo
{	
	int 	_deviceCount;
} GlobleInfo;
GlobleInfo *gInfo;
typedef struct _remoteConfig
{
	int 	_deviceId;//id
	char	_deviceType[100];//type
	char    _ipAddress[100];//ip
	char	_port[100];//port
	char	_loginuser[100];//user
	char	_loginpsw[100];//psw
	char    _timeout[100];//timeout
	char    _autoReconnect[100];//autoReconnect
	char    _reconnectInterval[100];//reconnectInterval
	int 	_status;//0表示已布放;-1表示未布防;-2连接失败
	int		_errorCode;//<0为自定义错误;>0为SDK错误码
	LONG    _lUserID;//相机
	LONG    _lHandle;//相机
} RemoteConfig,RemoteConfig1;
RemoteConfig *config;

 char log_path[100]="/image_root/a.log";
 int log_size=0;
 int i=0;//随机数的范围
 int rev_num;//相机二次布放的状态
 int failnum;//发送地址失败的数组下标
 int log_model=3;
 int log_level=0;
 int curl_timeout=30;
 CURL *curl;
void FORK() 
{ 
int pid; 
int i; 
if(pid=fork()) 
	exit(0);//是父进程，结束父进程 
else if(pid< 0) 
	exit(1);//fork失败，退出 
//是第一子进程，后台继续执行 
setsid();//第一子进程成为新的会话组长和进程组长 
//并与控制终端分离 
if(pid=fork()) 
	exit(0);//是第一子进程，结束第一子进程 
else if(pid< 0) 
	exit(1);//fork失败，退出 
//是第二子进程，继续 
//第二子进程不再是会话组长 
for(i=0;i< NOFILE;++i)//关闭打开的文件描述符 
	close(i); 
chdir("/");//改变工作目录到/tmp 
umask(0);//重设文件创建掩模 
return; 
} 


void Log(char *buff,int loglevel){
		LOG *g=CreateLogHandleG();
        if(g == NULL )
        {
                //printf( "创建日志句柄失败errno[%d]\n" , errno );
				
                return ;
        }
		//char logpath[20];
		//sprintf(logpath,"/usr/local/gcstorage/test/HK.log");
        SetLogOutputG( LOG_OUTPUT_FILE , log_path, LOG_NO_OUTPUTFUNC );
        SetLogLevelG( log_level );//LOG_LEVEL_INFO
		if (log_model==1){
			SetLogRotateSize(g,log_size); 
		}
		SetLogRotateMode(g,log_model); //设置转档模式
        SetLogStylesG( LOG_STYLES_HELLO , LOG_NO_STYLEFUNC);
		//WriteLog(g,__FILE__ , __LINE__ ,loglevel,buff);
       // SetLogRotateMode(LOG_ROTATEMODE_PER_DAY );
        //以不同日志等级写行日志 
       switch (loglevel) {
		case 0: DEBUGLOGG(buff); break;
		case 1: INFOLOGG(buff);  break;
		case 2: WARNLOGG(buff);  break;
		case 3: ERRORLOGG(buff);  break;
		case 4: FATALLOGG(buff); break;
		default : break;
		
		}
        //销毁日志句柄 
		 DestroyLogHandleG();
}
////////////////////////////////////////////////////////////////////////////

void curlpost(PHOTO_INFO res_send,char* url){
	char logcurl[20];
	sprintf(logcurl,"CURL START");
	Log(logcurl,DEBUG);
	std::cout<<"curl"<<std::endl;
	//CURL *curl;
	struct curl_httppost *post = NULL;
	struct curl_httppost *last  = NULL;
	
	//char* buff = res_send.pBuffer1.data;
	//long buff_length = res_send.pBuffer1.length;
	printf("发送地址为:%s\n",url);
	curl_global_init(CURL_GLOBAL_ALL);
	struct curl_slist *chunk = NULL;
	//curl = curl_easy_init();
	if (curl ==NULL) {
		curl = curl_easy_init();
	}
	if(curl) {
		curl_formadd(&post, &last,
               CURLFORM_COPYNAME, "qjtx",
               CURLFORM_BUFFER, "hiki.jpg",
               CURLFORM_BUFFERPTR, res_send.qjtx.data,
               CURLFORM_BUFFERLENGTH, res_send.qjtx.length,
               CURLFORM_END);
		if (res_send.pBuffer2.length>=1){
		curl_formadd(&post, &last,
               CURLFORM_COPYNAME, "gfile2",
               CURLFORM_BUFFER, "plate.jpg",
               CURLFORM_BUFFERPTR, res_send.pBuffer2.data,
               CURLFORM_BUFFERLENGTH, res_send.pBuffer2.length,
               CURLFORM_END);
		}

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "cd", 
				CURLFORM_PTRCONTENTS, res_send.cd, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "jgsj", 
				CURLFORM_PTRCONTENTS, res_send.jgsj, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "zpxh", 
				CURLFORM_PTRCONTENTS, res_send.zpxh, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "hphm", 
				CURLFORM_PTRCONTENTS, res_send.hphm, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "clsd", 
				CURLFORM_PTRCONTENTS, res_send.clsd, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "clpp", 
				CURLFORM_PTRCONTENTS, res_send.clpp, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "hpys", 
				CURLFORM_PTRCONTENTS, res_send.hpys, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "wfdm", 
				CURLFORM_PTRCONTENTS, res_send.wfdm, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "zb", 
				CURLFORM_PTRCONTENTS, res_send.zb, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "csys", 
				CURLFORM_PTRCONTENTS, res_send.csys, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "sbip", 
				CURLFORM_PTRCONTENTS, res_send.sbip, 
				CURLFORM_END);

		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "txxh", 
				CURLFORM_PTRCONTENTS, res_send.txxh, 
				CURLFORM_END);
			
		curl_formadd(&post, &last, 
				CURLFORM_COPYNAME, "cllk", 
				CURLFORM_PTRCONTENTS, res_send.cllk, 
				CURLFORM_END);
		
		// 初始化libcurl
		chunk = curl_slist_append(chunk, "Connection: Keep-Alive"); 
	    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
		//curl_easy_setopt(curl,CURLOPT_URL, POSTURL);
		curl_easy_setopt(curl,CURLOPT_TCP_KEEPALIVE, 1);
		curl_easy_setopt(curl,CURLOPT_TCP_KEEPIDLE, 10);
		curl_easy_setopt(curl,CURLOPT_TCP_KEEPINTVL, 5);
		//curl_easy_setopt(curl,CURLOPT_URL,config[gInfo->_deviceCount-1]._postip);
		curl_easy_setopt(curl,CURLOPT_URL,url);
		curl_easy_setopt(curl, CURLOPT_POST, 1);
		curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, curl_timeout);	
		CURLcode res = curl_easy_perform(curl);
		if(res != CURLE_OK) {
      		if (res == CURLE_COULDNT_CONNECT){
				resend[failnum].url_status=-1;
			}
			fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
			  /*char err[20];
			sprintf(err,"curl_easy_perform() failed: %s",curl_easy_strerror(res));
				Log(err,ERROR);*/
		}
		curl_formfree(post);
		post = NULL;
	    last  = NULL;
		//curl_easy_cleanup(curl);
	}
	curl_global_cleanup();	
	
	char logcurl2[20];
	sprintf(logcurl2,"CURL OVER");
	Log(logcurl2,DEBUG);
	//delete logcurl2;

}
char* rand_url();
void CALLBACK MessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void *pUser) 
{ 
    char logcall[20];
	sprintf(logcall,"CALLBACK START");
	Log(logcall,DEBUG);
	//delete logcall;
	PHOTO_INFO res_send; 
	//printf("lCommand:%d\n",lCommand);
    NET_DVR_PLATE_RESULT struPlateResult={0}; 
    memcpy(&struPlateResult, pAlarmInfo, sizeof(struPlateResult)); 
	sprintf(res_send.cd,"%d",struPlateResult.byChanIndex);
	res_send.jgsj=struPlateResult.byAbsTime;
	res_send.hphm=struPlateResult.struPlateInfo.sLicense;
	sprintf(res_send.clsd,"%d",struPlateResult.struVehicleInfo.wSpeed);
	res_send.sbip=pAlarmer->sDeviceIP;
	char s[20];
	sprintf(s,"%f,%f,%f,%f",struPlateResult.struPlateInfo.struPlateRect.fX,struPlateResult.struPlateInfo.struPlateRect.fY,struPlateResult.struPlateInfo.struPlateRect.fWidth,struPlateResult.struPlateInfo.struPlateRect.fHeight);
	res_send.zb=s;
	sprintf(res_send.cllk,"%d",struPlateResult.byVehicleType);
	sprintf(res_send.txxh,"%d",struPlateResult.struVehicleInfo.dwIndex);
	sprintf(res_send.zpxh,"%d",struPlateResult.byPicNum);
	
	//sprintf(res_send.hpys,"%d",struPlateResult.struPlateInfo.byColor);//需要转义的字段
	
	//sprintf(res_send.wfdm,"%d",struPlateResult.struVehicleInfo.byIllegalType);//需要转义的字段
	
	sprintf(res_send.clpp,"%c",struPlateResult.struVehicleInfo.byVehicleLogoRecog);//需要转义的字段
	
	//sprintf(res_send.csys,"%d",struPlateResult.struVehicleInfo.byColor);//需要转义的字段
	if (struPlateResult.struPlateInfo.byColor<=4){
		strcpy(res_send.hpys,tb_hpys[struPlateResult.struPlateInfo.byColor]);
		std::cout<<"号牌颜色"<<res_send.hpys<<std::endl;
	}

	//sprintf(res_send.wfdm,"%d",struPlateResult.struVehicleInfo.byIllegalType);
	if (struPlateResult.struVehicleInfo.byIllegalType<=14){
		strcpy(res_send.wfdm,tb_wfxwdm[struPlateResult.struVehicleInfo.byIllegalType]);
		std::cout<<"违反代码"<<res_send.wfdm<<std::endl;
	}

	
	//sprintf(res_send.clpp,"%c",struPlateResult.struVehicleInfo.byVehicleLogoRecog);
	//sprintf(res_send.csys,"%d",struPlateResult.struVehicleInfo.byColor);
	if (struPlateResult.struVehicleInfo.byColor<=13){
		strcpy(res_send.csys,tb_csys[struPlateResult.struVehicleInfo.byColor]);
		std::cout<<"车身颜色"<<res_send.csys<<std::endl;
	}
	res_send.qjtx.length = struPlateResult.dwPicLen;
	res_send.pBuffer2.length = struPlateResult.dwPicPlateLen;
	//printf("dwPicLen:%d\n",struPlateResult.dwPicLen);
	res_send.qjtx.data =(unsigned char *)malloc(struPlateResult.dwPicLen + 1);
	res_send.pBuffer2.data =(unsigned char *)malloc(struPlateResult.dwPicPlateLen + 1);/* 根据文件大小动态分配内存空间 */
	memcpy(res_send.qjtx.data,struPlateResult.pBuffer1,struPlateResult.dwPicLen);
	memcpy(res_send.pBuffer2.data,struPlateResult.pBuffer2,struPlateResult.dwPicPlateLen);
	//printf("curl post is start\n");
	
	curlpost(res_send,rand_url());
	free(res_send.qjtx.data);
	res_send.qjtx.data=NULL;
	if (res_send.pBuffer2.length>=1){
		free(res_send.pBuffer2.data);
		res_send.pBuffer2.data=NULL;
	}
	std::cout<<"CALLBACK end"<<std::endl;
	char logcall2[20];
	sprintf(logcall2,"CALLBACK OVER");
	Log(logcall2,DEBUG);
	//delete logcall2;
} 
char* rand_url(){
	int t=0;
	
	for (int j=0;j<i;j++){
		srand(time(0));       //seed
		t = rand() % i;
		if (resend[t].url_status==0){
			failnum=t;
			return resend[t].resend_url;
		}
	}
} 
void geturl(char* sendurl);
//增加布防
Json::Value doAdd(Json::Value  json_object) {
	char logadd[20];
	sprintf(logadd,"cmd add start");
	Log(logadd,DEBUG);
	printf("布防命令");
	//std::cout<<"doAdd"<<std::endl;
	//printf("add device count :%d\n",gInfo->_deviceCount);
	Json::Value jaResponse;
	Json::Value joResSingle;
	Json::Value content = json_object["content"];
	int num  = content.size();//相机数量
	int num2=gInfo->_deviceCount;
	char s[100];
	strcpy(s,json_object["url"].asString().c_str());
	geturl(s);
	if (rev_num==0){
		//gInfo->_deviceCount = num;	
		config = new RemoteConfig[100];
	}else{
		for (int j=0;j<num;j++){//将重复的没有布防成功的相机筛选出来
			for (int i=0;i<gInfo->_deviceCount;i++){
				printf("筛选相机start");
				printf("相机id'%d\n",content[j]["id"].asInt());
				printf("内存id：%d\n",config[i]._deviceId);
				printf("内存状态：%d\n",config[i]._status);
				if(content[j]["id"].asInt()==config[i]._deviceId && config[i]._status!=0){	
					printf("筛选相机");
					for (int a=0;a<gInfo->_deviceCount;a++){
						config[i]=config[i+1];
					}
					gInfo->_deviceCount--;
				}
				else if(content[j]["id"].asInt()==config[i]._deviceId && config[i]._status == 0){
					joResSingle["id"] = config[i]._deviceId;
					joResSingle["status"] = config[i]._status;
					jaResponse.append(joResSingle);
					for (int a=0;a<num;a++){
						content[j] = content[j+1];
					}
					num--;
					
				}
			}
		}
	}
	//NET_DVR_SetConnectTime(2000, 1); 
	//	NET_DVR_SetReconnect(10000, true);  
	rev_num=1;
	//std::cout<<"rev_num"<<std::endl;
	int num1=gInfo->_deviceCount;
	
	for (int i=0;i<num;i++){
		printf("布防device count:%d\n",gInfo->_deviceCount);
		config[gInfo->_deviceCount]._deviceId = content[i]["id"].asInt();
		printf("布防config：%d\n",config[gInfo->_deviceCount]._deviceId);
		strcpy(config[gInfo->_deviceCount]._ipAddress,content[i]["host"].asString().c_str());
		strcpy(config[gInfo->_deviceCount]._port,content[i]["port"].asString().c_str());
		strcpy(config[gInfo->_deviceCount]._loginuser,content[i]["user"].asString().c_str());
		strcpy(config[gInfo->_deviceCount]._loginpsw,content[i]["pass"].asString().c_str());
		strcpy(config[gInfo->_deviceCount]._deviceType,content[i]["camera_type"].asString().c_str());
		config[gInfo->_deviceCount]._status = -1;//初始
		gInfo->_deviceCount++;
	}
	if (!NET_DVR_Init()) {
		//config[i]._errorCode = -9;
		/*char loginit[20];
		sprintf(loginit,"初始化失败");
		Log(loginit,ERROR);*/
		
		return 0;
	}
	//NET_DVR_SetConnectTime(2000, 1); 
	//NET_DVR_SetReconnect(10000, true);
	for (int i=0;i<num;i++){
		NET_DVR_SetConnectTime(content[i]["time_out"].asInt(), content[i]["con_num"].asInt()); 
		NET_DVR_SetReconnect(content[i]["recon_time"].asInt(), true);  
		NET_DVR_DEVICEINFO_V30 struDeviceInfo; 
		config[num1]._lUserID = NET_DVR_Login_V30(config[num1]._ipAddress, atoi(config[num1]._port), config[num1]._loginuser, config[num1]._loginpsw, &struDeviceInfo); 
		if (config[num1]._lUserID<0) {
			config[num1]._status = -2;
			config[num1]._errorCode = NET_DVR_GetLastError();
			printf("连接失败：%d",config[num1]._errorCode);
		}
		//
		if (!NET_DVR_SetDVRMessageCallBack_V30(MessageCallback, NULL)) {
			config[num1]._errorCode = NET_DVR_GetLastError();
			printf("调用callback函数失败:%d\n",config[num1]._errorCode);
			joResSingle["id"] = config[num1]._deviceId;
			joResSingle["status"] = config[num1]._status;
			printf("调用callback函数status:%d\n",config[num1]._status);
			jaResponse.append(joResSingle);
			continue;
		}
		//
		NET_DVR_SETUPALARM_PARAM struSetupParam={0}; 
		struSetupParam.dwSize=sizeof(NET_DVR_SETUPALARM_PARAM); 
		//
		struSetupParam.byAlarmInfoType=content[i]["ptc_mod"].asInt();
		printf("布防模式:%d\n",struSetupParam.byAlarmInfoType);
		//struSetupParam.byAlarmInfoType=0;
		//struSetupParam.byLevel = 1;
		//布防等级，0-2，0表示最高级1级，1表示2级（支持同时2台设备布防），2表示3级 
		struSetupParam.byLevel = content[i]["ptc_level"].asInt();
		printf("布防等级:%d\n",struSetupParam.byLevel);
		config[num1]._lHandle = NET_DVR_SetupAlarmChan_V41(config[num1]._lUserID,&struSetupParam); 
		if (config[num1]._lHandle<0 &&config[num1]._lUserID>=0) {
			config[num1]._status = -1;   //布防失败
			config[num1]._errorCode = NET_DVR_GetLastError();
			printf("布防失败:%d\n",config[num1]._errorCode);
			char logadd1[20];
			sprintf(logadd1,"布防失败,errorCode:%d",config[num1]._errorCode);
			Log(logadd1,ERROR);
		}
		else if (config[num1]._lUserID<0) 
		{
			config[num1]._status = -2;
		}		else {
			//布防成功
			config[num1]._status = 0;
		}
		joResSingle["id"] = config[num1]._deviceId;
		joResSingle["status"] = config[num1]._status;
		jaResponse.append(joResSingle);
		printf("num1%d\n",num1);
		printf("config id： %d\n",config[num1]._deviceId);
		num1++;
		
	}
	//printf("device count :%d\n",gInfo->_deviceCount);
	return jaResponse;
}


Json::Value doDel(Json::Value  json_object) {
	/*char logdel[20];
	sprintf(logdel,"cmd del start");
	Log(logdel,DEBUG);*/
	printf("撤防命令");
	Json::Value content = json_object["content"];
	int num  = content.size();
	Json::Value jaResponse;
	Json::Value joResSingle;
	int  num1=gInfo->_deviceCount;
	for(int i=0;i<num;i++) {
		int deviceId = content[i]["id"].asInt();
		for(int j=0;j<num1;j++) {
			if (config[j]._deviceId==deviceId ) {
				//撤防
				if ( (config[j]._lHandle!=-1)&&(!NET_DVR_CloseAlarmChan_V30(config[j]._lHandle)) )
				{
					config[j]._errorCode = NET_DVR_GetLastError();
				} else {
					config[j]._status = -1;//撤防成功
				}
				//释放SDK资源
				try{	
					//注销用户
					if (config[j]._lUserID>=0)
					{
						if ( !NET_DVR_Logout(config[j]._lUserID) )	{
							config[j]._errorCode = NET_DVR_GetLastError();
						}
					}
					
				}catch(...){
				}
				
				joResSingle["id"] = config[j]._deviceId;
				printf("已撤防id：%d",config[j]._deviceId);
				joResSingle["status"] = config[j]._status;
				printf("已撤防相机状态：%d",config[j]._status);
				jaResponse.append(joResSingle);
				if (config[j]._status = -1 ){
					for (int a=0;a<gInfo->_deviceCount;a++){
						config[j]=config[j+1];
					}
					gInfo->_deviceCount--;
				}
				break;
			}
			else if(config[j]._deviceId==deviceId && config[j]._status != 0){
				joResSingle["id"] = config[j]._deviceId;
				printf("已撤防id：%d",config[j]._deviceId);
				joResSingle["status"] = config[j]._status;
				printf("已撤防相机状态：%d",config[j]._status);
				jaResponse.append(joResSingle);
				for (int a=0;a<gInfo->_deviceCount;a++){
					config[j]=config[j+1];
				}
				gInfo->_deviceCount--;
				break;
			}
			if (gInfo->_deviceCount<1){
					rev_num = 0;
					delete []config;
					return jaResponse;
			}
		}
	}
	return jaResponse;
}

Json::Value Check(Json::Value  json_object) {
	/* char logCheck[20];
	sprintf(logCheck,"cmd Check start");
	Log(logCheck,DEBUG);*/
	 Json::Value jaResponse;
	 Json::Value joResSingle;
	/* CURL *curl1;
	 struct curl_httppost *post = NULL;
	 curl_global_init(CURL_GLOBAL_ALL);
	 curl1 = curl_easy_init();
     curl_easy_setopt(curl1, CURLOPT_URL, "http:192.168.2.133/secline/gcs/application/check");// /secline/gcs/application/check
     curl_easy_setopt(curl1, CURLOPT_POST, 1);
     curl_easy_setopt(curl1, CURLOPT_HTTPPOST, post);
	 curl_easy_setopt(curl1, CURLOPT_TIMEOUT, 30);	
	 CURLcode res = curl_easy_perform(curl1);
	 curl_formfree(post);
     curl_easy_cleanup(curl1);
	 curl_global_cleanup();	
	if(res != CURLE_OK) {
		joResSingle["code"] ="-1";
		joResSingle["msg"] ="server extremely";//服务器异常
		jaResponse.append(joResSingle);
	    return jaResponse;
		
	}*/
	joResSingle["code"] ="0";
	joResSingle["msg"] ="OK";
	jaResponse.append(joResSingle);
	return jaResponse;
}
void geturl(char* sendurl){
	i=0;
	char* d=sendurl;
	int t;
	char *a=NULL;
	while((d=strtok_r(d,",",&a))!=NULL)  {
		//strcpy(send_url[i],a);
		strcpy(resend[i].resend_url,d);
		resend[i].url_status = 0;
		d=NULL;
		i++;
	}
}
Json::Value Config(Json::Value  json_object) {
	printf("config 开始");
	Json::Value content = json_object["content"];
	Json::Value jaResponse;
	Json::Value joResSingle;
	log_size = content["log_rotatesize"].isNull()?0:content["log_rotatesize"].asInt();
	log_level = content["log_level"].isNull()?LOG_LEVEL_INFO:content["log_level"].asInt();
	log_model = content["log_rotatemode"].isNull()?LOG_ROTATEMODE_PER_HOUR:content["log_rotatemode"].asInt();
	//strcpy(send_url,content["url"].asString().c_str());
	/*for(int i=0;i<10;i++){
		strcpy(send_url[i],strsep(content[i],";");
	}
	*/
		
	if (content["curl_timeout"].isNull()){
		curl_timeout=30;
	}
	else if (content["curl_timeout"].asInt()!=curl_timeout){
		curl_timeout=content["curl_timeout"].asInt();
	}
	if (content["log_path"].isNull()){
		sprintf(log_path,"/image_root/a.log");
	}
	else{
		strcpy(log_path,content["log_path"].asString().c_str());
	}
	std::cout<<content["url"].asString().c_str()<<std::endl;
	char r[50];
	sprintf(r,"%c",content["url"].asString().c_str());
	geturl(r);
	
	joResSingle["code"] ="0";
	joResSingle["msg"] ="OK";
	jaResponse.append(joResSingle);
	return jaResponse;
}


Json::Value doMonitor(Json::Value  json_object) {
	char logdoMonitor[20];
	sprintf(logdoMonitor,"cmd doMonitor start");
	Log(logdoMonitor,DEBUG);
	Json::Value content = json_object["content"];
	int num  = content.size();
	Json::Value jaResponse;
	Json::Value joResSingle; 
	int idnum=0;
	for(int i=0;i<num;i++) {
		int deviceId = content[i]["id"].asInt();
		for(int j=0;j<gInfo->_deviceCount;j++) {
			if (config[j]._deviceId==deviceId) {
				idnum++;
				joResSingle["id"] = config[j]._deviceId;
				joResSingle["status"] = config[j]._status;
				jaResponse.append(joResSingle);
			}

		}	
		if (idnum == 0){
		joResSingle["id"] = deviceId;
		joResSingle["msg"] = "no id";
		jaResponse.append(joResSingle);
	}
	}
	
	return jaResponse;
}

Json::Value doMonitorall(Json::Value  json_object) {
	char logdoMonitorall[20];
	// res[];
	sprintf(logdoMonitorall,"cmd doMonitorall start");
	Log(logdoMonitorall,DEBUG);
	Json::Value jaResponse;
	Json::Value joResSingle; 
	char *re="{}";
	if (gInfo->_deviceCount==0){
		
	    return re;
	}
	for(int j=0;j<gInfo->_deviceCount;j++) {
		joResSingle["id"] = config[j]._deviceId;
		joResSingle["status"] = config[j]._status;
		jaResponse.append(joResSingle);
		
	}
	return jaResponse;
}

Json::Value Monitorurl(Json::Value  json_object) {

	Json::Value jaResponse;
	Json::Value joResSingle; 
	for(int j=0;j<i;j++) {
		joResSingle["url"] = resend[j].resend_url;
		joResSingle["status"] = resend[j].url_status;
		jaResponse.append(joResSingle);
	}
	return jaResponse;
}
Json::Value doDelall(Json::Value  json_object) {
	printf("exit 命令");
	Json::Value jaResponse;
	Json::Value joResSingle;
	if(gInfo->_deviceCount==0){
		return 0;
	}
	for(int j=0;j<gInfo->_deviceCount;j++) {
			//撤防
		if ( (config[j]._lHandle!=-1)&&(!NET_DVR_CloseAlarmChan_V30(config[j]._lHandle)) )
		{
			config[j]._errorCode = NET_DVR_GetLastError();
		} else {
			config[j]._status = -1;//撤防成功
		}
		//释放SDK资源
		try{	
			//注销用户
			if (config[j]._lUserID>=0)
			{
				if ( !NET_DVR_Logout(config[j]._lUserID) )	{
					config[j]._errorCode = NET_DVR_GetLastError();
				}
			}
		}catch(...){
		}
		if (config[j]._status = -1){
			config[j]=config[j+1];
			gInfo->_deviceCount--;
		}
		joResSingle["id"] = config[j]._deviceId;
	    joResSingle["status"] = config[j]._status;
		jaResponse.append(joResSingle);
	}
	rev_num=0;
	
	delete []config;
	return jaResponse;
}


int sendResponse(Json::Value jaResponse, void* z_socket) {
	Json::FastWriter writer;
	//char* s ;
	std::string res = writer.write(jaResponse);
	std::cout<<res<<std::endl;
		//zmq_msg_send();
		zmq_msg_t send_msg;
		zmq_msg_init_size(&send_msg,res.size());
		//strcpy(s,res.c_str());
		//memcpy(zmq_msg_data(&send_msg),&s,res.size());
		memcpy(zmq_msg_data(&send_msg),res.c_str(),res.size());
		zmq_sendmsg(z_socket,&send_msg,0);
		zmq_msg_close(&send_msg);
	return 0;
}
int stop(char* argv[]) {
	void* context=zmq_init(1);    //指定zmq 处理I/0事件的thread pool 为1
    void* z_socket=zmq_socket(context,ZMQ_REQ);
    zmq_connect(z_socket,argv[2]);    // accept connections on a socket
	Json::FastWriter writer;
	Json::Value joResSingle;
	joResSingle["cmd"] = "exit";
	std::string res = writer.write(joResSingle);	
        //发送部分
	zmq_msg_t send_msg;
	zmq_msg_init_size(&send_msg,res.size());
	memcpy(zmq_msg_data(&send_msg),res.c_str(),res.size());
	//zmq_msg_send(&send_msg,z_socket,0);
	zmq_sendmsg(z_socket,&send_msg,0);
	zmq_msg_close(&send_msg);

	//接受部分
	zmq_msg_t recv_msg;
	zmq_msg_init(&recv_msg);
	zmq_msg_recv(&recv_msg,z_socket,0);                    //0表示非阻塞
	zmq_msg_close(&recv_msg);
    zmq_close(z_socket);
    zmq_term(context);     
    return 0;
}
int start(char* argv[]) 
{
	
	/*char logstart[20];//="start cmd";
	strcpy(logstart,"start cmd");
	//sprintf(logstart,"%s","start cmd");*/
	
	curl = curl_easy_init();
	//Log(logstart,DEBUG);
    std::cout << "-------------------Zeromq REP style-----------------------" <<std::endl;
    std::cout << "---------------------Author:Gcstorage------------------------" <<std::endl;
	//FORK();
	gInfo = new GlobleInfo;
	gInfo->_deviceCount = 0;
	resend=new Resive[100];
	/*if (!NET_DVR_Init()) {
			//config[i]._errorCode = -9;
			char loginit[20];
			sprintf(loginit,"初始化失败");
			Log(loginit,ERROR);
			
			return 0;
		};*/
    void* context=zmq_init(1); 
    void* z_socket=zmq_socket(context,ZMQ_REP);
    zmq_bind(z_socket,argv[2]);   
	Json::Reader reader;
    Json::Value json_object;
	//RemoteConfig *config;
    while(1)   
    {    
    	zmq_msg_t recv_msg;
    	zmq_msg_init(&recv_msg);
        zmq_msg_recv(&recv_msg,z_socket,0);  
		char* receive = (char*)zmq_msg_data(&recv_msg);
		
		zmq_msg_close(&recv_msg);
		if (receive!=NULL) {
			try{
				if (reader.parse(receive, json_object)) {
				
					std::string cmd = json_object["cmd"].asString();
					char logcmd[20];
					sprintf(logcmd,"cmd logcmd start");
					Log(logcmd,DEBUG);
					if (cmd=="add") {
					
						sendResponse(doAdd(json_object),z_socket);
						
					} else if (cmd=="del"){
					  
						sendResponse(doDel(json_object),z_socket);
						
					} else if (cmd=="monitor") {
					
						sendResponse(doMonitor(json_object),z_socket);
						
					} else if (cmd=="config") {
					
						sendResponse(Config(json_object),z_socket);
						
					}else if (cmd=="monitor_all") {
					
						sendResponse(doMonitorall(json_object),z_socket);
						
					} else if (cmd =="check"){
					    
						sendResponse(Check(json_object),z_socket);
					}
					else if (cmd =="monitor_url"){
					    
						sendResponse(Monitorurl(json_object),z_socket);
					}
					else if (cmd =="delall"){
					    
						sendResponse(doDelall(json_object),z_socket);
					}
					else if (cmd =="exit"){
						sendResponse(doDelall(json_object),z_socket);
						exit(0);
					}
					else {
						//printf("cmd::%s",cmd);
						std::cout<<"cmd"<<cmd<<std::endl;
						Json::Value jaResponse;
						Json::Value joResSingle;
						joResSingle["warn"] ="not command,please input again!";
						jaResponse.append(joResSingle);
						sendResponse(jaResponse,z_socket);
					}
				}
			}
			catch (...)
			{
			}
			
		}

    }
    zmq_close(z_socket);
    zmq_term(context);
    return 0;
}
int  main (int arg ,char* argv[]){
	std::string str=argv[1];
	int sta=0;
	if (str=="start"){
		sta=1;
	}else if (str=="stop"){
		sta=2;
	}
	switch (sta){
	case 1: start(argv);break;
	case 2: stop(argv);exit(1);break;
	}
}









